package us.versus.them.stickler.graphics;

#if js
import js.Lib;
import js.Dom;

import us.versus.them.stickler.Point;
import us.versus.them.stickler.graphics.borrowed.JsCanvas;

class JsGraphics implements ThinGraphics {

	var jsCanvas : JsCanvas;
	var timer : haxe.Timer;

	var enterFrameOps : Array< Void -> Void >;
	var mouseDownOps  : Array< Int -> Int -> Void >;
	var mouseMoveOps  : Array< Int -> Int -> Void >;
	var mouseUpOps    : Array< Int -> Int -> Void >;

	public function new( canvasId : String, ?fps : Int ) {

		this.enterFrameOps = new Array< Void -> Void >();
		this.mouseDownOps  = new Array< Int -> Int -> Void >();
		this.mouseMoveOps  = new Array< Int -> Int -> Void >();
		this.mouseUpOps    = new Array< Int -> Int -> Void >();

		jsCanvas = new JsCanvas( Lib.document.getElementById( canvasId ) );
		if ( 0 == fps ) {
			fps = 20;
		}

		timer = new haxe.Timer( Math.round( 1000 / fps ) );
		timer.run = handleEnterFrame;

		var me = this;
		Lib.document.onmousemove = function( e:Event ) me.handleMouseMove( e.clientX, e.clientY );
		Lib.document.onmouseup   = function( e:Event ) me.handleMouseUp( e.clientX, e.clientY );
		Lib.document.onmousedown = function( e:Event ) me.handleMouseDown( e.clientX, e.clientY );
	}

	public function addEnterFrame( enterFrame : Void -> Void ) : Void {
		this.enterFrameOps.push( enterFrame );
	}

	public function addMouseDown( mouseDown : Int -> Int -> Void ): Void {
		this.mouseDownOps.push( mouseDown );
	}

	public function addMouseMove( mouseMove : Int -> Int -> Void ): Void {
		this.mouseMoveOps.push( mouseMove );
	}
	
	public function addMouseUp( mouseUp : Int -> Int -> Void ): Void {
		this.mouseUpOps.push( mouseUp );
	}

	public function clear(): Void {
		this.jsCanvas.clear();
	}

	public function drawBox( point : Point, size : Point, color : Int ): Void {
		this.jsCanvas.beginFill( color, 0 );
		this.jsCanvas.drawRect( point.x, point.y, size.x, size.y );
		this.jsCanvas.endFill();
	}

	public function drawLine( start : Point, stop : Point ): Void {
		this.jsCanvas.ctx.beginPath();
		this.jsCanvas.moveTo( start.x, start.y );
		this.jsCanvas.lineTo( stop.x, stop.y );
		this.jsCanvas.ctx.closePath();
		this.jsCanvas.ctx.stroke();
	}

	////

	public function handleEnterFrame() {
		for ( enterFrameOp in enterFrameOps ) {
			enterFrameOp();
		}
	}

	public function handleMouseMove( x : Int, y : Int ) {
		for ( mouseDownOp in mouseDownOps ) {
			mouseDownOp( x, y );
		}
	}

	public function handleMouseUp( x : Int, y : Int ) {
		for ( mouseMoveOp in mouseMoveOps ) {
			mouseMoveOp( x, y );
		}
	}

	public function handleMouseDown( x : Int, y : Int ) {
		for ( mouseUpOp in mouseUpOps ) {
			mouseUpOp( x, y );
		}
	}

}

#end
